#  This file is part of FlickFleck.
#  Copyright (C) 2008 Jyke Tapani Jokinen
#
#    FlickFleck is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    FlickFleck is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with FlickFleck.  If not, see <http://www.gnu.org/licenses/>.
#
import config
import ui
import os, os.path
import tempfile
from subprocess import Popen, PIPE
from fileops import copy, quotepath

#
# map orientation values to jpegtran commands to make the pic right
# data is from
# http://sylvana.net/jpegcrop/exif_orientation.html
TRANS = [
	[ "" ],  # not in use
	[ "" ],
	[ "-flip horizontal" ],
	[ "-rotate 180 -trim" ],
	[ "-flip vertical" ],
	[ "-transpose" ],
	[ "-rotate 90 -trim" ],
	[ "-transverse" ],
	[ "-rotate 90 -trim", "-rotate 180 -trim" ]
]

# --------------------------------------------------------------------
def rotate( filename ):
  dir  = os.path.dirname(  filename )
  file = os.path.basename( filename )

  # --a no duplicate tags
  # -f force printing of tags even if values are not found (0 is unknown)
  # -n print values as numbers
  cmd = config.exiftool + " --a -f -fast -n -Orientation " + \
      quotepath(filename)

  try:
    pipe = Popen(cmd, shell=True, stdout=PIPE)
    pipe.wait()
    if pipe.returncode != 0:
      ui.ERR("problem running exiftool (read orientation1) (%s)" % filename )
      
    # parse orientation
    (str, data) = pipe.stdout.readline().split(':', 1)
  except:
    ui.ERR( "exception in exiftool (read orientation2) (%s)" % filename )

  if str.strip().lower() != "orientation":
	ui.ERR( "exiftool: orientation not found (%s)" % str )

  orientation = int( data.strip() )
  if orientation > 8:
    ui.ERR( "orientation out of range (%d,%s)" % (orientation, filename) )

  # 0 : unknown orientation -> do not touch
  # 1 : horizontal orientation -> no need to rotate
  if orientation == 0 or orientation == 1:
    return

  #
  # execute rotation operations defined in table 'TRANS'
  # rotations are written to a new file which is copied to the
  # original file in the last step
  #
  fromfile = filename
  tmpfiles = []
  for op in TRANS[ orientation ]:
    (fd, tmp) = tempfile.mkstemp( '', '', dir )
    os.close(fd)
    # XXX: closing tmpfile and using the filename creates a race condition
    # but target is usually in users subdirectory and this program is usually
    # run in a personal computer, so risk should be minimal/acceptable
    tmpfiles.append( tmp ) # record name for cleanup later

    # -copy all preserves original EXIF information
    rot_cmd = config.jpegtran + " -copy all -outfile " \
              + quotepath(tmp) + " " + op + " " + quotepath(fromfile)
    try:
      pipe = Popen( rot_cmd, shell=True, stdout=PIPE)
      pipe.wait()
      if pipe.returncode != 0:
        ui.ERR("problem running jpegtran (%s)" % fromfile )
    except:
      ui.ERR("exception in jpegtran (%s)" % rot_cmd )
    fromfile = tmp
  # endfor

  # move the last resultfile into original name
  if fromfile != filename: 
    try:
      os.remove( filename )
      os.rename( fromfile, filename )
    except:
      ui.ERR("error finalizing jpegtran (%s)" % filename )

  # rotation should have made the picture into 'horizontal' orientation so
  # change the orientation EXIF info to match that
  cmd = config.exiftool + " -overwrite_original_in_place -n -Orientation=1 " \
      + quotepath(filename)
  try:
    pipe = Popen(cmd, shell=True, stdout=PIPE)
    pipe.wait()
    if pipe.returncode != 0:
      ui.ERR("problem running exiftool (set orientation) (%s)" % filename )
  except:
    ui.ERR( "exception in exiftool (set orientation) (%s)" % filename )


  # remove any tempfiles still present in the filesystem
  for f in tmpfiles:
    if os.path.exists( f ):
      try:
        os.remove( f )
      except:
        ui.ERR("cannot remove tempfile (%s)" % f )
